#include "stdafx.h"
#include "gp.h"
#include "gp_Ax3.h"
#include "gp_Ax1.h"
#include "gp_Pnt.h"
#include "gp_Ax2.h"
#include "gp_Trsf.h"
#include "gp_Vec.h"
#include "gp_Cylinder.h"

 gp_Cylinder::gp_Cylinder ()
{ radius = DBL_MAX; }

 gp_Cylinder::gp_Cylinder (const gp_Ax3& A3,
				 const double Radius) :
				 pos(A3),
				 radius (Radius)
{ 
 Standard_ConstructionError_Raise_if(Radius < 0.0, "");
 }

 void gp_Cylinder::SetAxis (const gp_Ax1& A1)
{ pos.SetAxis (A1); }

 void gp_Cylinder::SetLocation (const gp_Pnt& Loc)
{ pos.SetLocation (Loc); }

 void gp_Cylinder::SetPosition (const gp_Ax3& A3)
{ pos = A3; }

 void gp_Cylinder::SetRadius (const double R)
{
Standard_ConstructionError_Raise_if(R < 0.0, "");
  radius = R;
}

 void gp_Cylinder::UReverse()
{ pos.YReverse(); }

 void gp_Cylinder::VReverse()
{ pos.ZReverse(); }

 bool gp_Cylinder::Direct() const
{ return pos.Direct(); }

 const gp_Ax1&  gp_Cylinder::Axis () const
{ return pos.Axis(); }

 const gp_Pnt&  gp_Cylinder::Location () const
{ return pos.Location(); }

 const gp_Ax3&  gp_Cylinder::Position () const
{ return pos; }

 double gp_Cylinder::Radius () const
{ return radius; }

 gp_Ax1 gp_Cylinder::XAxis () const
{return gp_Ax1(pos.Location(), pos.XDirection());}

 gp_Ax1 gp_Cylinder::YAxis () const
{return gp_Ax1(pos.Location(), pos.YDirection());}

 void gp_Cylinder::Rotate (const gp_Ax1& A1,
				 const double Ang)
{pos.Rotate(A1,Ang);}

 gp_Cylinder gp_Cylinder::Rotated (const gp_Ax1& A1,
					 const double Ang) const
{
  gp_Cylinder C = *this;
  C.pos.Rotate (A1, Ang);
  return C;
}

 void gp_Cylinder::Scale (const gp_Pnt& P, const double S)
{
  pos.Scale (P, S);      
  radius *= S;
  if (radius < 0) radius = - radius;
}

 gp_Cylinder gp_Cylinder::Scaled (const gp_Pnt& P,
					const double S) const
{
  gp_Cylinder C = *this;
  C.pos.Scale (P, S);
  C.radius *= S;
  if (C.radius < 0) C.radius = - C.radius;
  return C;
}

 void gp_Cylinder::Transform (const gp_Trsf& T)
{
  pos.Transform (T);
  radius *= T.ScaleFactor();
  if (radius < 0) radius = - radius;
}

 gp_Cylinder gp_Cylinder::Transformed (const gp_Trsf& T) const
{
  gp_Cylinder C = *this;
  C.pos.Transform (T);
  C.radius *= T.ScaleFactor();
  if (C.radius < 0) C.radius = - C.radius;
  return C;
}

 void gp_Cylinder::Translate (const gp_Vec& V)
{ pos.Translate (V); }

 gp_Cylinder gp_Cylinder::Translated (const gp_Vec& V) const
{
  gp_Cylinder C = *this;
  C.pos.Translate (V);
  return C;
}

 void gp_Cylinder::Translate (const gp_Pnt& P1,
				    const gp_Pnt& P2)
{ pos.Translate (P1, P2); }

 gp_Cylinder gp_Cylinder::Translated (const gp_Pnt& P1,
					    const gp_Pnt& P2) const
{
  gp_Cylinder C = *this;
  C.pos.Translate (P1, P2);
  return C;
}

 void gp_Cylinder::Coefficients
	 (double& A1, double& A2, double& A3, 
	 double& B1, double& B2, double& B3, 
	 double& C1, double& C2, double& C3, double& D) const
 {
	 // Dans le repere local du cylindre :
	 // X**2 + Y**2 - radius = 0.0
	 gp_Trsf T;
	 T.SetTransformation (pos);
	 double T11 = T.Value (1, 1);
	 double T12 = T.Value (1, 2);
	 double T13 = T.Value (1, 3);
	 double T14 = T.Value (1, 4);
	 double T21 = T.Value (2, 1);
	 double T22 = T.Value (2, 2);
	 double T23 = T.Value (2, 3);
	 double T24 = T.Value (2, 4);

	 A1 = T11 * T11 + T21 * T21;
	 A2 = T12 * T12 + T22 * T22;
	 A3 = T13 * T13 + T23 * T23;
	 B1 = T11 * T12 + T21 * T22;
	 B2 = T11 * T13 + T21 * T23;
	 B3 = T12 * T13 + T22 * T23;
	 C1 = T11 * T14 + T21 * T24;
	 C2 = T12 * T14 + T22 * T24;
	 C3 = T13 * T14 + T23 * T24;
	 D  = T14 * T14 + T24 * T24 - radius * radius;  
 }

 void gp_Cylinder::Mirror (const gp_Pnt& P)
 { pos.Mirror (P); }

 gp_Cylinder gp_Cylinder::Mirrored (const gp_Pnt& P) const
 {
	 gp_Cylinder C = *this;
	 C.pos.Mirror (P);
	 return C;
 }

 void gp_Cylinder::Mirror (const gp_Ax1& A1)
 { pos.Mirror (A1); }

 gp_Cylinder gp_Cylinder::Mirrored (const gp_Ax1& A1) const
 {
	 gp_Cylinder C = *this;
	 C.pos.Mirror (A1);
	 return C;
 }

 void gp_Cylinder::Mirror (const gp_Ax2& A2)
 { pos.Mirror (A2); }

 gp_Cylinder gp_Cylinder::Mirrored (const gp_Ax2& A2) const
 {
	 gp_Cylinder C = *this;
	 C.pos.Mirror (A2);
	 return C;
 }